<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>数据状态管理 | East'blog</title><meta name="author" content="侯玉东"><meta name="copyright" content="侯玉东"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="数据状态管理">
<meta property="og:type" content="article">
<meta property="og:title" content="数据状态管理">
<meta property="og:url" content="https://houyudong1989.gitee.io/blog/2023/11/28/harmonyOS/%E6%95%B0%E6%8D%AE%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/index.html">
<meta property="og:site_name" content="East&#39;blog">
<meta property="og:description" content="数据状态管理">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://houyudong1989.gitee.io/blog/img/library1.jpeg">
<meta property="article:published_time" content="2023-11-27T16:00:00.000Z">
<meta property="article:modified_time" content="2024-03-22T09:46:55.623Z">
<meta property="article:author" content="侯玉东">
<meta property="article:tag" content="harmonyOS">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://houyudong1989.gitee.io/blog/img/library1.jpeg"><link rel="shortcut icon" href="/blog/img/head.jpg"><link rel="canonical" href="https://houyudong1989.gitee.io/blog/2023/11/28/harmonyOS/%E6%95%B0%E6%8D%AE%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/blog/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = {
  root: '/blog/',
  algolia: undefined,
  localSearch: undefined,
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  dateSuffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  infinitegrid: {
    js: 'https://cdn.jsdelivr.net/npm/@egjs/infinitegrid/dist/infinitegrid.min.js',
    buttonText: '加载更多'
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: false,
  },
  autoDarkmode: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: '数据状态管理',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2024-03-22 17:46:55'
}</script><script>(win=>{
      win.saveToLocal = {
        set: (key, value, ttl) => {
          if (ttl === 0) return
          const now = Date.now()
          const expiry = now + ttl * 86400000
          const item = {
            value,
            expiry
          }
          localStorage.setItem(key, JSON.stringify(item))
        },
      
        get: key => {
          const itemStr = localStorage.getItem(key)
      
          if (!itemStr) {
            return undefined
          }
          const item = JSON.parse(itemStr)
          const now = Date.now()
      
          if (now > item.expiry) {
            localStorage.removeItem(key)
            return undefined
          }
          return item.value
        }
      }
    
      win.getScript = (url, attr = {}) => new Promise((resolve, reject) => {
        const script = document.createElement('script')
        script.src = url
        script.async = true
        script.onerror = reject
        script.onload = script.onreadystatechange = function() {
          const loadState = this.readyState
          if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
          script.onload = script.onreadystatechange = null
          resolve()
        }

        Object.keys(attr).forEach(key => {
          script.setAttribute(key, attr[key])
        })

        document.head.appendChild(script)
      })
    
      win.getCSS = (url, id = false) => new Promise((resolve, reject) => {
        const link = document.createElement('link')
        link.rel = 'stylesheet'
        link.href = url
        if (id) link.id = id
        link.onerror = reject
        link.onload = link.onreadystatechange = function() {
          const loadState = this.readyState
          if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
          link.onload = link.onreadystatechange = null
          resolve()
        }
        document.head.appendChild(link)
      })
    
      win.activateDarkMode = () => {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = () => {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
        if (t === 'dark') activateDarkMode()
        else if (t === 'light') activateLightMode()
      
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
      const detectApple = () => {
        if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
          document.documentElement.classList.add('apple')
        }
      }
      detectApple()
    })(window)</script><meta name="generator" content="Hexo 6.3.0"></head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><script>(()=>{
  const $loadingBox = document.getElementById('loading-box')
  const $body = document.body
  const preloader = {
    endLoading: () => {
      $body.style.overflow = ''
      $loadingBox.classList.add('loaded')
    },
    initLoading: () => {
      $body.style.overflow = 'hidden'
      $loadingBox.classList.remove('loaded')
    }
  }

  preloader.initLoading()
  window.addEventListener('load',() => { preloader.endLoading() })

  if (true) {
    document.addEventListener('pjax:send', () => { preloader.initLoading() })
    document.addEventListener('pjax:complete', () => { preloader.endLoading() })
  }
})()</script><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/blog/img/head.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/blog/archives/"><div class="headline">文章</div><div class="length-num">70</div></a><a href="/blog/tags/"><div class="headline">标签</div><div class="length-num">26</div></a><a href="/blog/categories/"><div class="headline">分类</div><div class="length-num">18</div></a></div><hr class="custom-hr"/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/blog/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/blog/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/blog/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/blog/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/blog/link/"><i class="fa-fw fas fa-link"></i><span> 友联</span></a></div><div class="menus_item"><a class="site-page" href="/blog/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg fixed" id="page-header" style="background-image: url('/blog/img/library6.jpeg')"><nav id="nav"><span id="blog-info"><a href="/blog/" title="East'blog"><img class="site-icon" src="/blog/img/head.jpg"/><span class="site-name">East'blog</span></a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page" href="/blog/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/blog/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/blog/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/blog/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/blog/link/"><i class="fa-fw fas fa-link"></i><span> 友联</span></a></div><div class="menus_item"><a class="site-page" href="/blog/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">数据状态管理</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2023-11-27T16:00:00.000Z" title="发表于 2023-11-28 00:00:00">2023-11-28</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2024-03-22T09:46:55.623Z" title="更新于 2024-03-22 17:46:55">2024-03-22</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/blog/categories/harmonyOS/">harmonyOS</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="数据状态管理"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="globalThis"><a href="#globalThis" class="headerlink" title="globalThis"></a>globalThis</h1><blockquote>
<p>ArkTS引擎实例内部的一个全局对象，在ArkTS引擎实例内部都能访问,每个应用都有且仅有一个globalThis，引擎内部的UIAbility&#x2F;ExtensionAbility&#x2F;Page都可以使用，因此可以使用globalThis全局对象进行数据同步。当给globalThis设置值的时候，如果值不存在则新增，存在则替换。所以在赋值的时候一定要注意这一点。</p>
</blockquote>
<p><img src="1701078284326.png" alt="1701078284326"></p>
<p><img src="1701078442877.png" alt="1701078442877"></p>
<blockquote>
<p>globalThis 使用</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">* globalThis 赋值</span><br><span class="line">	globalThis.context = this.context</span><br><span class="line"></span><br><span class="line">* globalThis 取值</span><br><span class="line">        let ctx = globalThis.context;</span><br></pre></td></tr></table></figure>

<h1 id="EventHub"><a href="#EventHub" class="headerlink" title="EventHub"></a>EventHub</h1><blockquote>
<p>基于发布订阅模式来实现，事件需要先订阅后发布，订阅者收到消息后进行处理。目前测试只能从页面触发事件给UIAbility进行响应。</p>
<p>EventHub主要包含3个函数，分别是订阅事件、取消订阅事件和发布事件。</p>
<p>基类context提供了EventHub对象，通过context获取eventHub对象，实现组件级别的事件传递机制。</p>
</blockquote>
<blockquote>
<p>要想实现更丰富的消息传递和订阅，可以参考emitter【@ohos.events.emitter (Emitter)】和 @ohos.commonEventManager (公共事件模块)</p>
</blockquote>
<blockquote>
<p>订阅事件</p>
<p>EventHub.on</p>
<p>on(event: string, callback: Function): void;</p>
<p>event：事件名称</p>
<p>callback： 事件回调，事件触发后执行</p>
</blockquote>
<p><img src="1701077640498.png" alt="1701077640498"></p>
<blockquote>
<p>发布事件</p>
<p>EventHub.emit</p>
<p>emit(event: string, …args: Object[]): void;</p>
<p>event：事件名称</p>
<p>args：可变参数，事件触发时，传递给回调函数的参数。</p>
</blockquote>
<p><img src="1701077599213.png" alt="1701077599213"></p>
<blockquote>
<p>取消订阅事件</p>
<p>EventHub.off</p>
<p>off(event: string, callback?: Function): void;</p>
<p>event：事件名称</p>
<p>callback：当callback传值时，取消订阅指定的callback；未传值时，取消订阅该事件下所有callback。</p>
</blockquote>
<p><img src="1701077678779.png" alt="1701077678779"></p>
<h1 id="localstorage-页面级UI状态存储"><a href="#localstorage-页面级UI状态存储" class="headerlink" title="localstorage 页面级UI状态存储"></a>localstorage 页面级UI状态存储</h1><blockquote>
<p>页面级UI状态存储，通过@Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility内，页面间共享状态。</p>
<ul>
<li>应用程序可以创建多个LocalStorage实例，LocalStorage实例可以在页面内共享，也可以通过GetShared接口，获取在UIAbility里创建的GetShared，实现跨页面、UIAbility内共享。</li>
<li>组件树的根节点，即被@Entry装饰的@Component，可以被分配一个LocalStorage实例，此组件的所有子组件实例将自动获得对该LocalStorage实例的访问权限；</li>
<li>被@Component装饰的组件最多可以访问一个LocalStorage实例和AppStorage，未被@Entry装饰的组件不可被独立分配LocalStorage实例，只能接受父组件通过@Entry传递来的LocalStorage实例。一个LocalStorage实例在组件树上可以被分配给多个组件。</li>
<li>LocalStorage中的所有属性都是可变的。</li>
</ul>
<p>应用程序决定LocalStorage对象的生命周期。当应用释放最后一个指向LocalStorage的引用时，比如销毁最后一个自定义组件，LocalStorage将被JS Engine垃圾回收。</p>
<p>LocalStorage根据与@Component装饰的组件的同步类型不同，提供了两个装饰器：</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-localstorage-0000001524537149-V3#section14665991077">@LocalStorageProp</a>：@LocalStorageProp装饰的变量和与LocalStorage中给定属性建立单向同步关系。</li>
<li><a target="_blank" rel="noopener" href="https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-localstorage-0000001524537149-V3#section20745122910311">@LocalStorageLink</a>：@LocalStorageLink装饰的变量和在@Component中创建与LocalStorage中给定属性建立双向同步关系。</li>
</ul>
</blockquote>
<h2 id="限制条件"><a href="#限制条件" class="headerlink" title="限制条件"></a>限制条件</h2><ul>
<li>LocalStorage创建后，命名属性的类型不可更改。后续调用Set时必须使用相同类型的值。</li>
<li>LocalStorage是页面级存储，<a target="_blank" rel="noopener" href="https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/arkts-state-management-0000001504151156-V3#ZH-CN_TOPIC_0000001523808562__getshared9">GetShared</a>接口仅能获取当前Stage通过<a target="_blank" rel="noopener" href="https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/js-apis-window-0000001477981397-V3#ZH-CN_TOPIC_0000001573929313__loadcontent9">windowStage.loadContent</a>传入的LocalStorage实例，否则返回undefined。</li>
</ul>
<h2 id="LocalStorageProp-key"><a href="#LocalStorageProp-key" class="headerlink" title="@LocalStorageProp(key)"></a>@LocalStorageProp(key)</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@LocalStorageProp(key)是和LocalStorage中key对应的属性建立单向数据同步，我们允许本地改变的发生，但是对于@LocalStorageProp，本地的修改永远不会同步回LocalStorage中，相反，如果LocalStorage给定key的属性发生改变，改变会被同步给@LocalStorageProp，并覆盖掉本地的修改。</span><br></pre></td></tr></table></figure>

<h3 id="装饰器使用规则说明"><a href="#装饰器使用规则说明" class="headerlink" title="装饰器使用规则说明"></a>装饰器使用规则说明</h3><table>
<thead>
<tr>
<th align="left">@LocalStorageProp变量装饰器</th>
<th align="left">说明</th>
</tr>
</thead>
<tbody><tr>
<td align="left">装饰器参数</td>
<td align="left">key：常量字符串，必填（字符串需要有引号）。</td>
</tr>
<tr>
<td align="left">允许装饰的变量类型</td>
<td align="left">Object、class、string、number、boolean、enum类型，以及这些类型的数组。嵌套类型的场景请参考<a target="_blank" rel="noopener" href="https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-localstorage-0000001524537149-V3#section95308721319">观察变化和行为表现</a>。类型必须被指定，且必须和LocalStorage中对应属性相同。不支持any，不允许使用undefined和null。</td>
</tr>
<tr>
<td align="left">同步类型</td>
<td align="left">单向同步：从LocalStorage的对应属性到组件的状态变量。组件本地的修改是允许的，但是LocalStorage中给定的属性一旦发生变化，将覆盖本地的修改。</td>
</tr>
<tr>
<td align="left">被装饰变量的初始值</td>
<td align="left">必须指定，如果LocalStorage实例中不存在属性，则作为初始化默认值，并存入LocalStorage中。</td>
</tr>
</tbody></table>
<h3 id="变量的传递-访问规则说明"><a href="#变量的传递-访问规则说明" class="headerlink" title="变量的传递&#x2F;访问规则说明"></a>变量的传递&#x2F;访问规则说明</h3><table>
<thead>
<tr>
<th align="left">传递&#x2F;访问</th>
<th align="left">说明</th>
</tr>
</thead>
<tbody><tr>
<td align="left">从父节点初始化和更新</td>
<td align="left">禁止，@LocalStorageProp不支持从父节点初始化，只能从LocalStorage中key对应的属性初始化，如果没有对应key的话，将使用本地默认值初始化。</td>
</tr>
<tr>
<td align="left">初始化子节点</td>
<td align="left">支持，可用于初始化@State、@Link、@Prop、@Provide。</td>
</tr>
<tr>
<td align="left">是否支持组件外访问</td>
<td align="left">否。</td>
</tr>
</tbody></table>
<p><img src="1701135935071.png" alt="1701135935071"></p>
<h2 id="LocalStorageLink-key"><a href="#LocalStorageLink-key" class="headerlink" title="@LocalStorageLink(key)"></a>@LocalStorageLink(key)</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">如果我们需要将自定义组件的状态变量的更新同步回LocalStorage，就需要用到@LocalStorageLink。</span><br><span class="line"></span><br><span class="line">@LocalStorageLink(key)是和LocalStorage中key对应的属性建立双向数据同步：</span><br><span class="line"></span><br><span class="line">本地修改发生，该修改会被写回LocalStorage中；</span><br><span class="line">LocalStorage中的修改发生后，该修改会被同步到所有绑定LocalStorage对应key的属性上，包括单向（@LocalStorageProp和通过prop创建的单向绑定变量）、双向（@LocalStorageLink和通过link创建的双向绑定变量）变量。</span><br></pre></td></tr></table></figure>

<h3 id="装饰器使用规则说明-1"><a href="#装饰器使用规则说明-1" class="headerlink" title="装饰器使用规则说明"></a>装饰器使用规则说明</h3><table>
<thead>
<tr>
<th align="left">@LocalStorageLink变量装饰器</th>
<th align="left">说明</th>
</tr>
</thead>
<tbody><tr>
<td align="left">装饰器参数</td>
<td align="left">key：常量字符串，必填（字符串需要有引号）。</td>
</tr>
<tr>
<td align="left">允许装饰的变量类型</td>
<td align="left">Object、class、string、number、boolean、enum类型，以及这些类型的数组。嵌套类型的场景请参考<a target="_blank" rel="noopener" href="https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-localstorage-0000001524537149-V3#section0207123614516">观察变化和行为表现</a>。类型必须被指定，且必须和LocalStorage中对应属性相同。不支持any，不允许使用undefined和null。</td>
</tr>
<tr>
<td align="left">同步类型</td>
<td align="left">双向同步：从LocalStorage的对应属性到自定义组件，从自定义组件到LocalStorage对应属性。</td>
</tr>
<tr>
<td align="left">被装饰变量的初始值</td>
<td align="left">必须指定，如果LocalStorage实例中不存在属性，则作为初始化默认值，并存入LocalStorage中。</td>
</tr>
</tbody></table>
<h3 id="变量的传递-访问规则说明-1"><a href="#变量的传递-访问规则说明-1" class="headerlink" title="变量的传递&#x2F;访问规则说明"></a>变量的传递&#x2F;访问规则说明</h3><table>
<thead>
<tr>
<th align="left">传递&#x2F;访问</th>
<th align="left">说明</th>
</tr>
</thead>
<tbody><tr>
<td align="left">从父节点初始化和更新</td>
<td align="left">禁止，@LocalStorageLink不支持从父节点初始化，只能从LocalStorage中key对应的属性初始化，如果没有对应key的话，将使用本地默认值初始化。</td>
</tr>
<tr>
<td align="left">初始化子节点</td>
<td align="left">支持，可用于初始化@State、@Link、@Prop、@Provide。</td>
</tr>
<tr>
<td align="left">是否支持组件外访问</td>
<td align="left">否。</td>
</tr>
</tbody></table>
<p><img src="1701136080358.png" alt="1701136080358"></p>
<h2 id="使用场景"><a href="#使用场景" class="headerlink" title="使用场景"></a>使用场景</h2><h3 id="UI内部使用LocalStorage"><a href="#UI内部使用LocalStorage" class="headerlink" title="UI内部使用LocalStorage"></a>UI内部使用LocalStorage</h3><blockquote>
<p>在同一个page页面中，所有Component共享一个localstorage，通过LocalStorageLink绑定的数据在修改以后会会写到LocalStorage中，这时候会影响LocalStorageLink和LocalStorageProp绑定的数据，但是通过LocalStorageProp不会回写到LocalStorage中，只会影响当前LocalStorageProp绑定的数据，而LocalStorageLink绑定的数据不受影响。</p>
</blockquote>
<p><img src="1701137211874.png" alt="1701137211874"></p>
<p><img src="1701137223215.png" alt="1701137223215"></p>
<p><img src="1701137235266.png" alt="1701137235266"></p>
<h3 id="UIAbility在多个UI页面共享一个-LocalStorage"><a href="#UIAbility在多个UI页面共享一个-LocalStorage" class="headerlink" title="UIAbility在多个UI页面共享一个 LocalStorage"></a>UIAbility在多个UI页面共享一个 LocalStorage</h3><blockquote>
<p>在UIAbility中创建LocalStorage，并通过loadContent传递给page，在page中通过调用LocalStorage.GetShared()获得storage实例，以达到多UI页面共享一个storage的效果。</p>
</blockquote>
<p><img src="1701138045507.png" alt="1701138045507"></p>
<p><img src="1701138065954.png" alt="1701138065954"></p>
<p><img src="1701138087748.png" alt="1701138087748"></p>
<h1 id="AppStorage-应用全局的UI状态存储"><a href="#AppStorage-应用全局的UI状态存储" class="headerlink" title="AppStorage 应用全局的UI状态存储"></a>AppStorage 应用全局的UI状态存储</h1><blockquote>
<p>AppStorage是应用全局的UI状态存储，是和应用的进程绑定的，由UI框架在应用程序启动时创建，为应用程序UI状态属性提供中央存储。</p>
<p>AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储，这些状态数据在应用级别都是可访问的。AppStorage将在应用运行过程保留其属性。属性通过唯一的键字符串值访问。</p>
<p>AppStorage可以和UI组件同步，且可以在应用业务逻辑中被访问。</p>
<p>AppStorage中的属性可以被双向同步，数据可以是存在于本地或远程设备上，并具有不同的功能，比如数据持久化。这些数据是通过业务逻辑中实现，与UI解耦，如果希望这些数据在UI中使用，需要用到@StorageProp和@StorageLink 。</p>
</blockquote>
<blockquote>
<p>AppStorage.SetOrCreate(‘age’, 47); 该函数在应用中创建了一个age字段，并赋值初始值为47.这时候可以在页面中使用@StorageProp和@StorageLink去关联这个字段，当然，我们也可以直接使用@StorageProp和@StorageLink区关联一个字段，他会先去判断AppStorage中是否有这个字段，如果没有就会在AppStorage中去创建一个字段，初始值则为设置的初始值。当我们结束应用以后，存储的数据会消失，下一次再次使用又会变成初始值，如果要记录上一次修改的数据就需要用到PersistentStorage持久化存储。</p>
</blockquote>
<h1 id="PersistentStorage-持久化存储UI状态"><a href="#PersistentStorage-持久化存储UI状态" class="headerlink" title="PersistentStorage 持久化存储UI状态"></a>PersistentStorage 持久化存储UI状态</h1><blockquote>
<p>要将数据持久化保存，我们可以先使用PersistentStorage.PersistProp(‘age’, 47);来设置字段，这时候再用@StorageProp和@StorageLink去关联该字段，就可以对数据进行持久化保存，当然，StorageProp修改的数据并不会写回PersistentStorage中，只有StorageLink关联的字段才会修改并保存。</p>
</blockquote>
<h1 id="Environment：设备环境查询"><a href="#Environment：设备环境查询" class="headerlink" title="Environment：设备环境查询"></a>Environment：设备环境查询</h1><blockquote>
<p>Environment是ArkUI框架在应用程序启动时创建的单例对象。它为AppStorage提供了一系列描述应用程序运行状态的属性。Environment的所有属性都是不可变的（即应用不可写入），所有的属性都是简单类型。</p>
<p>1、将设备的语言code存入AppStorage，默认值为en</p>
<p>Environment.EnvProp(‘languageCode’, ‘en’);</p>
<p>2、获取存入的设备语言</p>
<p>@StorageProp(‘languageCode’) lang : string &#x3D; ‘en’;</p>
<blockquote>
<p>注意：获取的数据修改不会进行持久化，当进程结束后再次打开又变成默认值</p>
</blockquote>
</blockquote>
<p><strong>内置环境变量说明：</strong></p>
<table>
<thead>
<tr>
<th align="left">key</th>
<th align="left">类型</th>
<th align="left">说明</th>
</tr>
</thead>
<tbody><tr>
<td align="left">accessibilityEnabled</td>
<td align="left">boolean</td>
<td align="left">无障碍屏幕朗读是否启用。</td>
</tr>
<tr>
<td align="left">colorMode</td>
<td align="left">ColorMode</td>
<td align="left">深浅色模式，可选值为：- ColorMode.LIGHT：浅色模式；- ColorMode.DARK：深色模式。</td>
</tr>
<tr>
<td align="left">fontScale</td>
<td align="left">number</td>
<td align="left">字体大小比例。</td>
</tr>
<tr>
<td align="left">fontWeightScale</td>
<td align="left">number</td>
<td align="left">字重比例。</td>
</tr>
<tr>
<td align="left">layoutDirection</td>
<td align="left">LayoutDirection</td>
<td align="left">布局方向类型，可选值为：- LayoutDirection.LTR：从左到右；- LayoutDirection.RTL：从右到左。</td>
</tr>
<tr>
<td align="left">languageCode</td>
<td align="left">string</td>
<td align="left">当前系统语言，小写字母，例如zh。</td>
</tr>
</tbody></table>
<h1 id="状态管理"><a href="#状态管理" class="headerlink" title="状态管理"></a>状态管理</h1><h2 id="State-装饰器"><a href="#State-装饰器" class="headerlink" title="@State 装饰器"></a>@State 装饰器</h2><blockquote>
<p>@State装饰的变量，或称为状态变量，一旦变量拥有了状态属性，就和自定义组件的渲染绑定起来。当状态改变时，UI会发生对应的渲染改变。<br>@State装饰的变量，与声明式范式中的其他被装饰变量一样，是私有的，只能从组件内部访问，在声明时必须指定其类型和本地初始化。初始化也可选择使用命名参数机制从父组件完成初始化。</p>
</blockquote>
<blockquote>
<p>@State装饰的变量拥有以下特点：<br>@State装饰的变量与子组件中的@Prop、@Link或@ObjectLink装饰变量之间建立单向或双向数据同步。<br>@State装饰的变量生命周期与其所属自定义组件的生命周期相同。</p>
</blockquote>
<blockquote>
<p>注意：不支持any，不支持嵌套属性的赋值，不支持Length、ResourceStr、ResourceColor类型，Length、ResourceStr、ResourceColor ，不支持简单类型和复杂类型的联合类型，不允许使用undefined和null。被装饰的变量必须本地初始化。</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct <span class="title class_">MyComponent</span> &#123;</span><br><span class="line"> </span><br><span class="line">  @<span class="title class_">State</span> <span class="attr">count</span>: number = <span class="number">0</span>;</span><br><span class="line"> </span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="title class_">Column</span>() &#123;</span><br><span class="line">      <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">count</span>.<span class="title function_">toString</span>())</span><br><span class="line">      <span class="title class_">Button</span>(<span class="string">&quot;点击更新UI&quot;</span>).<span class="title function_">onClick</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">        <span class="comment">// @State变量的更新将触发该Button组件的内容更新</span></span><br><span class="line">        <span class="variable language_">this</span>.<span class="property">count</span> +=<span class="number">1</span>;</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="Prop-装饰器"><a href="#Prop-装饰器" class="headerlink" title="@Prop 装饰器"></a>@Prop 装饰器</h2><blockquote>
<p>@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的，但是变化不会同步回其父组件。</p>
<p>@Prop装饰的变量和父组件建立单向的同步关系：</p>
<ul>
<li>@Prop变量允许在本地修改，但修改后的变化不会同步回父组件。</li>
<li>当父组件中的数据源更改时，与之相关的@Prop装饰的变量都会自动更新。如果子组件已经在本地修改了@Prop装饰的相关变量值，而在父组件中对应的@State装饰的变量被修改后，子组件本地修改的@Prop装饰的相关变量值将被覆盖。</li>
</ul>
</blockquote>
<blockquote>
<p>注意：</p>
<ul>
<li>@Prop修饰复杂类型时是深拷贝，在拷贝的过程中除了基本类型、Map、Set、Date、Array外，都会丢失类型。</li>
<li>@Prop装饰器不能在@Entry装饰的自定义组件中使用。</li>
<li>@Prop和<a target="_blank" rel="noopener" href="https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-state-management-overview-0000001524537145-V3#section127619262713">数据源</a>类型需要相同</li>
</ul>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">@<span class="title class_">Entry</span></span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct <span class="title class_">AppPage</span> &#123;</span><br><span class="line">  @<span class="title class_">State</span> <span class="attr">count</span>:number =<span class="number">10</span></span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="title class_">Column</span>() &#123;</span><br><span class="line">        <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">count</span>.<span class="title function_">toString</span>() )</span><br><span class="line">          .<span class="title function_">fontSize</span>(<span class="number">50</span>).<span class="title function_">margin</span>(<span class="number">20</span>)</span><br><span class="line">          .<span class="title function_">fontWeight</span>(<span class="title class_">FontWeight</span>.<span class="property">Bold</span>).<span class="title function_">onClick</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">            <span class="variable language_">this</span>.<span class="property">count</span>+=<span class="number">10</span> <span class="comment">//count发生变化会导致AppPage和Son的UI发生变化</span></span><br><span class="line">        &#125;)</span><br><span class="line">        <span class="title class_">Son</span>(&#123;<span class="attr">num</span>:<span class="variable language_">this</span>.<span class="property">count</span>&#125;) </span><br><span class="line">      &#125;</span><br><span class="line">      .<span class="title function_">width</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">    .<span class="title function_">height</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct <span class="title class_">Son</span> &#123;</span><br><span class="line">  @<span class="title class_">Prop</span> <span class="attr">num</span>:number</span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">num</span>.<span class="title function_">toString</span>() )</span><br><span class="line">      .<span class="title function_">fontSize</span>(<span class="number">50</span>)</span><br><span class="line">      .<span class="title function_">fontWeight</span>(<span class="title class_">FontWeight</span>.<span class="property">Bold</span>).<span class="title function_">onClick</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">          <span class="variable language_">this</span>.<span class="property">num</span> +=<span class="number">5</span>  <span class="comment">//Son的num发生变化只会影响Son，而不会影响AppPage</span></span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="Link-装饰器"><a href="#Link-装饰器" class="headerlink" title="@Link 装饰器"></a>@Link 装饰器</h2><blockquote>
<p>@Link装饰的变量与其父组件中的数据源共享相同的值。</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">@<span class="title class_">Entry</span></span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct <span class="title class_">AppPage</span> &#123;</span><br><span class="line">  @<span class="title class_">State</span> <span class="attr">count</span>:number =<span class="number">10</span></span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="title class_">Column</span>() &#123;</span><br><span class="line">        <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">count</span>.<span class="title function_">toString</span>() )</span><br><span class="line">          .<span class="title function_">fontSize</span>(<span class="number">50</span>).<span class="title function_">margin</span>(<span class="number">20</span>)</span><br><span class="line">          .<span class="title function_">fontWeight</span>(<span class="title class_">FontWeight</span>.<span class="property">Bold</span>).<span class="title function_">onClick</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">            <span class="variable language_">this</span>.<span class="property">count</span>+=<span class="number">10</span>  <span class="comment">//count发生变化会导致AppPage和Son的UI发生变化</span></span><br><span class="line">        &#125;)</span><br><span class="line">        <span class="title class_">Son</span>(&#123;<span class="attr">num</span>:$count&#125;) <span class="comment">//link方式传递需要使用$</span></span><br><span class="line">      &#125;</span><br><span class="line">      .<span class="title function_">width</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">    .<span class="title function_">height</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct <span class="title class_">Son</span> &#123;</span><br><span class="line">  @<span class="title class_">Link</span> <span class="attr">num</span>:number</span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">num</span>.<span class="title function_">toString</span>() )</span><br><span class="line">      .<span class="title function_">fontSize</span>(<span class="number">50</span>)</span><br><span class="line">      .<span class="title function_">fontWeight</span>(<span class="title class_">FontWeight</span>.<span class="property">Bold</span>).<span class="title function_">onClick</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">          <span class="variable language_">this</span>.<span class="property">num</span> +=<span class="number">5</span>  <span class="comment">//Son的num发生变化会同时影响Son和AppPage</span></span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="Provide和-Consume-装饰器"><a href="#Provide和-Consume-装饰器" class="headerlink" title="@Provide和@Consume 装饰器"></a>@Provide和@Consume 装饰器</h2><blockquote>
<p>@Provide和@Consume，应用于与后代组件的双向数据同步，应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递，@Provide和@Consume摆脱参数传递机制的束缚，实现跨层级传递。</p>
<p>其中@Provide装饰的变量是在祖先节点中，可以理解为被“提供”给后代的状态变量。@Consume装饰的变量是在后代组件中，去“消费（绑定）”祖先节点提供的变量。</p>
<p>使用方式：</p>
<ul>
<li>通过相同的变量名绑定<ul>
<li>@Provide count: number &#x3D; 10;</li>
<li>@Consume count: number;</li>
</ul>
</li>
<li>通过相同的变量别名绑定<ul>
<li>@Provide(‘count’) b: number &#x3D; 10;</li>
<li>@Consume(‘count’) c: number;</li>
</ul>
</li>
</ul>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">//父类和子孙类双向数据同步</span></span><br><span class="line">@<span class="title class_">Entry</span></span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct <span class="title class_">AppstoragePage</span> &#123;</span><br><span class="line">  @<span class="title class_">Provide</span> <span class="attr">count</span>: number = <span class="number">10</span>;</span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="title class_">Column</span>() &#123;</span><br><span class="line">        <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">count</span>.<span class="title function_">toString</span>() )</span><br><span class="line">          .<span class="title function_">fontSize</span>(<span class="number">50</span>).<span class="title function_">margin</span>(<span class="number">20</span>)</span><br><span class="line">          .<span class="title function_">fontWeight</span>(<span class="title class_">FontWeight</span>.<span class="property">Bold</span>).<span class="title function_">onClick</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">            <span class="variable language_">this</span>.<span class="property">count</span>+=<span class="number">10</span> </span><br><span class="line">        &#125;)</span><br><span class="line">      <span class="title function_">A</span>()</span><br><span class="line">      &#125;</span><br><span class="line">      .<span class="title function_">width</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">    .<span class="title function_">height</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct A &#123;</span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title function_">B</span>()</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct B &#123;</span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title function_">C</span>()</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct C &#123;</span><br><span class="line">  @<span class="title class_">Consume</span> <span class="attr">count</span>:number;</span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">count</span>.<span class="title function_">toString</span>() )</span><br><span class="line">      .<span class="title function_">fontSize</span>(<span class="number">50</span>)</span><br><span class="line">      .<span class="title function_">fontWeight</span>(<span class="title class_">FontWeight</span>.<span class="property">Bold</span>).<span class="title function_">onClick</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">          <span class="variable language_">this</span>.<span class="property">count</span> +=<span class="number">5</span></span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="Observed和-ObjectLink-装饰器"><a href="#Observed和-ObjectLink-装饰器" class="headerlink" title="@Observed和@ObjectLink 装饰器"></a>@Observed和@ObjectLink 装饰器</h2><blockquote>
<p>@ObjectLink和@Observed类装饰器用于在涉及嵌套对象或数组的场景中进行双向数据同步：</p>
<ul>
<li>被@Observed装饰的类，可以被观察到属性的变化；</li>
<li>子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例，和父组件中对应的状态变量建立双向数据绑定。这个实例可以是数组中的被@Observed装饰的项，或者是class object中的属性，这个属性同样也需要被@Observed装饰。</li>
<li>单独使用@Observed是没有任何作用的，需要搭配@ObjectLink或者@Prop使用。</li>
</ul>
</blockquote>
<h2 id="Watch-装饰器"><a href="#Watch-装饰器" class="headerlink" title="@Watch 装饰器"></a>@Watch 装饰器</h2><blockquote>
<p>@Watch应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变，可以使用@Watch为状态变量设置回调函数。</p>
<p>用于监听状态变量的变化，当状态变量变化时，@Watch的回调方法将被调用。</p>
</blockquote>
<h3 id="使用场景-1"><a href="#使用场景-1" class="headerlink" title="使用场景"></a>使用场景</h3><blockquote>
<p>@Watch和@State回调监听更新</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">@<span class="title class_">Entry</span></span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct <span class="title class_">WatchPage</span> &#123;</span><br><span class="line">  @<span class="title class_">State</span> @<span class="title class_">Watch</span>(<span class="string">&quot;callbackFun&quot;</span>)<span class="attr">message</span>: string = <span class="string">&#x27;回调执行&#x27;</span></span><br><span class="line"></span><br><span class="line">  <span class="title function_">callbackFun</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">message</span> = <span class="string">&quot;回调函数执行成功&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="title class_">Row</span>() &#123;</span><br><span class="line">      <span class="title class_">Column</span>() &#123;</span><br><span class="line">        <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">message</span>)</span><br><span class="line">          .<span class="title function_">fontSize</span>(<span class="number">20</span>)</span><br><span class="line">          .<span class="title function_">fontWeight</span>(<span class="title class_">FontWeight</span>.<span class="property">Bold</span>).<span class="title function_">onClick</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">            <span class="variable language_">this</span>.<span class="property">message</span> = <span class="string">&quot;gengai&quot;</span></span><br><span class="line">        &#125;)</span><br><span class="line">      &#125;</span><br><span class="line">      .<span class="title function_">width</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    .<span class="title function_">height</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>@Watch和@Prop回调监听更新</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">@<span class="title class_">Entry</span></span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct <span class="title class_">WatchPage</span> &#123;</span><br><span class="line">  @<span class="title class_">State</span>  <span class="attr">message</span>: string = <span class="string">&#x27;回调执行&#x27;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="title class_">Row</span>() &#123;</span><br><span class="line">      <span class="title class_">Column</span>() &#123;</span><br><span class="line">        <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">message</span>)</span><br><span class="line">          .<span class="title function_">fontSize</span>(<span class="number">20</span>)</span><br><span class="line">          .<span class="title function_">fontWeight</span>(<span class="title class_">FontWeight</span>.<span class="property">Bold</span>).<span class="title function_">onClick</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">            <span class="variable language_">this</span>.<span class="property">message</span> = <span class="string">&quot;gengai&quot;</span></span><br><span class="line">        &#125;)</span><br><span class="line">        <span class="title class_">Son</span>(&#123;<span class="attr">message</span>:<span class="variable language_">this</span>.<span class="property">message</span>&#125;)</span><br><span class="line">      &#125;</span><br><span class="line">      .<span class="title function_">width</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    .<span class="title function_">height</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct <span class="title class_">Son</span> &#123;</span><br><span class="line">  @<span class="title class_">Prop</span> @<span class="title class_">Watch</span>(<span class="string">&quot;callbackFun&quot;</span>)<span class="attr">message</span>: string</span><br><span class="line"></span><br><span class="line">  <span class="title function_">callbackFun</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">message</span> = <span class="string">&quot;回调函数执行成功&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="title class_">Row</span>() &#123;</span><br><span class="line">      <span class="title class_">Column</span>() &#123;</span><br><span class="line">        <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">message</span>)</span><br><span class="line">          .<span class="title function_">fontSize</span>(<span class="number">40</span>)</span><br><span class="line"></span><br><span class="line">      &#125;</span><br><span class="line">      .<span class="title function_">width</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    .<span class="title function_">height</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>@Watch和@Link回调监听</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">@<span class="title class_">Entry</span></span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct <span class="title class_">WatchPage</span> &#123;</span><br><span class="line">  @<span class="title class_">State</span>  <span class="attr">message</span>: string = <span class="string">&#x27;回调执行&#x27;</span></span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="title class_">Row</span>() &#123;</span><br><span class="line">      <span class="title class_">Column</span>() &#123;</span><br><span class="line">        <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">message</span>)</span><br><span class="line">          .<span class="title function_">fontSize</span>(<span class="number">20</span>)</span><br><span class="line">          .<span class="title function_">fontWeight</span>(<span class="title class_">FontWeight</span>.<span class="property">Bold</span>).<span class="title function_">onClick</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">            <span class="variable language_">this</span>.<span class="property">message</span> = <span class="string">&quot;gengai&quot;</span></span><br><span class="line">        &#125;)</span><br><span class="line">        <span class="title class_">Son</span>(&#123;<span class="attr">message</span>:$message&#125;)</span><br><span class="line">      &#125;</span><br><span class="line">      .<span class="title function_">width</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    .<span class="title function_">height</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line">@<span class="title class_">Component</span></span><br><span class="line">struct <span class="title class_">Son</span> &#123;</span><br><span class="line">  @<span class="title class_">Link</span> @<span class="title class_">Watch</span>(<span class="string">&quot;callbackFun&quot;</span>)<span class="attr">message</span>: string</span><br><span class="line"></span><br><span class="line">  <span class="title function_">callbackFun</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">message</span> = <span class="string">&quot;回调函数执行成功&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">build</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="title class_">Row</span>() &#123;</span><br><span class="line">      <span class="title class_">Column</span>() &#123;</span><br><span class="line">        <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">message</span>)</span><br><span class="line">          .<span class="title function_">fontSize</span>(<span class="number">40</span>)</span><br><span class="line"></span><br><span class="line">      &#125;</span><br><span class="line">      .<span class="title function_">width</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    .<span class="title function_">height</span>(<span class="string">&#x27;100%&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="Component"><a href="#Component" class="headerlink" title="@Component"></a>@Component</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">组件装饰器，由一个或多个系统控件组合而成。被@Component装饰的组件可以调用组件生命周期。</span><br><span class="line">aboutToAppear：组件即将出现时回调该接口，具体时机为在创建自定义组件的新实例后，在执行其build()函数之前执行。</span><br><span class="line">aboutToDisappear：在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量，特别是@Link变量的修改可能会导致应用程序行为不稳定。</span><br></pre></td></tr></table></figure>
<h2 id="Entry"><a href="#Entry" class="headerlink" title="@Entry"></a>@Entry</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">页面装饰器，由一个或多个自定义组件组成，为页面的入口组件，一个页面有且仅有一个@Entry，只有被@Entry装饰的组件才可以调用页面的生命周期。</span><br><span class="line">onPageShow：页面每次显示时触发一次，包括路由过程、应用进入前台等场景。</span><br><span class="line">onPageHide：页面每次隐藏时触发一次，包括路由过程、应用进入后台等场景。</span><br><span class="line">onBackPress：当用户点击返回按钮时触发。</span><br></pre></td></tr></table></figure>




<p><a target="_blank" rel="noopener" href="https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/uiability-data-sync-with-ui-0000001427744556-V3#ZH-CN_TOPIC_0000001574088345__uiability%E5%92%8Cpage%E4%B9%8B%E9%97%B4%E4%BD%BF%E7%94%A8globalthis">UIAbility组件与UI的数据同步</a></p>
<p><a target="_blank" rel="noopener" href="https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-application-state-management-overview-0000001529381989-V3">存储状态</a></p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta"><i class="fas fa-circle-user fa-fw"></i>文章作者: </span><span class="post-copyright-info"><a href="https://houyudong1989.gitee.io/blog">侯玉东</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta"><i class="fas fa-square-arrow-up-right fa-fw"></i>文章链接: </span><span class="post-copyright-info"><a href="https://houyudong1989.gitee.io/blog/2023/11/28/harmonyOS/%E6%95%B0%E6%8D%AE%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/">https://houyudong1989.gitee.io/blog/2023/11/28/harmonyOS/%E6%95%B0%E6%8D%AE%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta"><i class="fas fa-circle-exclamation fa-fw"></i>版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://houyudong1989.gitee.io/blog" target="_blank">East'blog</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/blog/tags/harmonyOS/">harmonyOS</a></div><div class="post_share"><div class="social-share" data-image="/blog/img/library1.jpeg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/blog/2023/11/29/harmonyOS/want%E6%98%BE%E5%BC%8F%E9%9A%90%E5%BC%8F%E8%A7%84%E5%88%99/" title="want显式隐式规则"><img class="cover" src="/blog/img/library1.jpeg" onerror="onerror=null;src='/blog/img/friend_404.gif'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">want显式隐式规则</div></div></a></div><div class="next-post pull-right"><a href="/blog/2023/11/24/harmonyOS/%E5%83%8F%E7%B4%A0%E5%8D%95%E4%BD%8D/" title="像素单位"><img class="cover" src="/blog/img/library1.jpeg" onerror="onerror=null;src='/blog/img/friend_404.gif'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">像素单位</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/blog/2024/01/20/harmonyOS/ArkUI-X/" title="ArkUI-X"><img class="cover" src="/blog/img/library1.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2024-01-20</div><div class="title">ArkUI-X</div></div></a></div><div><a href="/blog/2023/12/15/harmonyOS/Canvas%E7%BB%98%E5%88%B6%E6%8A%98%E7%BA%BF%E5%9B%BE/" title="canvas绘制折线图"><img class="cover" src="/blog/img/library1.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-12-15</div><div class="title">canvas绘制折线图</div></div></a></div><div><a href="/blog/2023/12/02/harmonyOS/Canvas%E7%BB%98%E5%88%B6%E6%9F%B1%E7%8A%B6%E5%9B%BE/" title="canvas绘制柱状图"><img class="cover" src="/blog/img/library1.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-12-02</div><div class="title">canvas绘制柱状图</div></div></a></div><div><a href="/blog/2024/03/25/harmonyOS/commonevent%E3%80%81eventhub%E3%80%81emitter%E5%92%8Cworker%E4%BD%BF%E7%94%A8/" title="commonevent、eventhub、emitter和worker使用"><img class="cover" src="/blog/img/library1.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2024-03-25</div><div class="title">commonevent、eventhub、emitter和worker使用</div></div></a></div><div><a href="/blog/2023/11/05/harmonyOS/hdc/" title="hdc 使用帮助"><img class="cover" src="/blog/img/library1.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-11-05</div><div class="title">hdc 使用帮助</div></div></a></div><div><a href="/blog/2023/12/26/harmonyOS/router%E8%B7%AF%E7%94%B1/" title="router路由跳转"><img class="cover" src="/blog/img/library1.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-12-26</div><div class="title">router路由跳转</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="/blog/img/head.jpg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">侯玉东</div><div class="author-info__description">生命不息，奋斗不止</div></div><div class="card-info-data site-data is-center"><a href="/blog/archives/"><div class="headline">文章</div><div class="length-num">70</div></a><a href="/blog/tags/"><div class="headline">标签</div><div class="length-num">26</div></a><a href="/blog/categories/"><div class="headline">分类</div><div class="length-num">18</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://gitee.com/houyudong1989"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://gitee.com/houyudong1989" target="_blank" title="Github"><i class="fab fa-github" style="color: #24292e;"></i></a><a class="social-icon" href="mailto:420098321@qq.com" target="_blank" title="Email"><i class="fas fa-envelope" style="color: #4a7dbe;"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">欢迎来到我的博客！！！</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#globalThis"><span class="toc-number">1.</span> <span class="toc-text">globalThis</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#EventHub"><span class="toc-number">2.</span> <span class="toc-text">EventHub</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#localstorage-%E9%A1%B5%E9%9D%A2%E7%BA%A7UI%E7%8A%B6%E6%80%81%E5%AD%98%E5%82%A8"><span class="toc-number">3.</span> <span class="toc-text">localstorage 页面级UI状态存储</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%99%90%E5%88%B6%E6%9D%A1%E4%BB%B6"><span class="toc-number">3.1.</span> <span class="toc-text">限制条件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#LocalStorageProp-key"><span class="toc-number">3.2.</span> <span class="toc-text">@LocalStorageProp(key)</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A3%85%E9%A5%B0%E5%99%A8%E4%BD%BF%E7%94%A8%E8%A7%84%E5%88%99%E8%AF%B4%E6%98%8E"><span class="toc-number">3.2.1.</span> <span class="toc-text">装饰器使用规则说明</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8F%98%E9%87%8F%E7%9A%84%E4%BC%A0%E9%80%92-%E8%AE%BF%E9%97%AE%E8%A7%84%E5%88%99%E8%AF%B4%E6%98%8E"><span class="toc-number">3.2.2.</span> <span class="toc-text">变量的传递&#x2F;访问规则说明</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#LocalStorageLink-key"><span class="toc-number">3.3.</span> <span class="toc-text">@LocalStorageLink(key)</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A3%85%E9%A5%B0%E5%99%A8%E4%BD%BF%E7%94%A8%E8%A7%84%E5%88%99%E8%AF%B4%E6%98%8E-1"><span class="toc-number">3.3.1.</span> <span class="toc-text">装饰器使用规则说明</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8F%98%E9%87%8F%E7%9A%84%E4%BC%A0%E9%80%92-%E8%AE%BF%E9%97%AE%E8%A7%84%E5%88%99%E8%AF%B4%E6%98%8E-1"><span class="toc-number">3.3.2.</span> <span class="toc-text">变量的传递&#x2F;访问规则说明</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-number">3.4.</span> <span class="toc-text">使用场景</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#UI%E5%86%85%E9%83%A8%E4%BD%BF%E7%94%A8LocalStorage"><span class="toc-number">3.4.1.</span> <span class="toc-text">UI内部使用LocalStorage</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#UIAbility%E5%9C%A8%E5%A4%9A%E4%B8%AAUI%E9%A1%B5%E9%9D%A2%E5%85%B1%E4%BA%AB%E4%B8%80%E4%B8%AA-LocalStorage"><span class="toc-number">3.4.2.</span> <span class="toc-text">UIAbility在多个UI页面共享一个 LocalStorage</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#AppStorage-%E5%BA%94%E7%94%A8%E5%85%A8%E5%B1%80%E7%9A%84UI%E7%8A%B6%E6%80%81%E5%AD%98%E5%82%A8"><span class="toc-number">4.</span> <span class="toc-text">AppStorage 应用全局的UI状态存储</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#PersistentStorage-%E6%8C%81%E4%B9%85%E5%8C%96%E5%AD%98%E5%82%A8UI%E7%8A%B6%E6%80%81"><span class="toc-number">5.</span> <span class="toc-text">PersistentStorage 持久化存储UI状态</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Environment%EF%BC%9A%E8%AE%BE%E5%A4%87%E7%8E%AF%E5%A2%83%E6%9F%A5%E8%AF%A2"><span class="toc-number">6.</span> <span class="toc-text">Environment：设备环境查询</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86"><span class="toc-number">7.</span> <span class="toc-text">状态管理</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#State-%E8%A3%85%E9%A5%B0%E5%99%A8"><span class="toc-number">7.1.</span> <span class="toc-text">@State 装饰器</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Prop-%E8%A3%85%E9%A5%B0%E5%99%A8"><span class="toc-number">7.2.</span> <span class="toc-text">@Prop 装饰器</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Link-%E8%A3%85%E9%A5%B0%E5%99%A8"><span class="toc-number">7.3.</span> <span class="toc-text">@Link 装饰器</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Provide%E5%92%8C-Consume-%E8%A3%85%E9%A5%B0%E5%99%A8"><span class="toc-number">7.4.</span> <span class="toc-text">@Provide和@Consume 装饰器</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Observed%E5%92%8C-ObjectLink-%E8%A3%85%E9%A5%B0%E5%99%A8"><span class="toc-number">7.5.</span> <span class="toc-text">@Observed和@ObjectLink 装饰器</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Watch-%E8%A3%85%E9%A5%B0%E5%99%A8"><span class="toc-number">7.6.</span> <span class="toc-text">@Watch 装饰器</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF-1"><span class="toc-number">7.6.1.</span> <span class="toc-text">使用场景</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Component"><span class="toc-number">7.7.</span> <span class="toc-text">@Component</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Entry"><span class="toc-number">7.8.</span> <span class="toc-text">@Entry</span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/blog/2024/05/06/c++/5%E3%80%81%E5%AD%97%E7%AC%A6%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2/" title="字符和字符串"><img src="/blog/img/library1.jpeg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="字符和字符串"/></a><div class="content"><a class="title" href="/blog/2024/05/06/c++/5%E3%80%81%E5%AD%97%E7%AC%A6%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2/" title="字符和字符串">字符和字符串</a><time datetime="2024-05-06T11:15:27.280Z" title="发表于 2024-05-06 19:15:27">2024-05-06</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2024/05/06/c++/4%E3%80%81%E6%8C%87%E9%92%88%E5%92%8C%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88/" title="指针和函数指针"><img src="/blog/img/library1.jpeg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="指针和函数指针"/></a><div class="content"><a class="title" href="/blog/2024/05/06/c++/4%E3%80%81%E6%8C%87%E9%92%88%E5%92%8C%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88/" title="指针和函数指针">指针和函数指针</a><time datetime="2024-05-06T11:14:29.047Z" title="发表于 2024-05-06 19:14:29">2024-05-06</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2024/05/05/python/7%E3%80%81m3u8%E8%A7%86%E9%A2%91%E6%A0%BC%E5%BC%8F/" title="m3u8格式"><img src="/blog/img/library1.jpeg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="m3u8格式"/></a><div class="content"><a class="title" href="/blog/2024/05/05/python/7%E3%80%81m3u8%E8%A7%86%E9%A2%91%E6%A0%BC%E5%BC%8F/" title="m3u8格式">m3u8格式</a><time datetime="2024-05-05T01:43:26.865Z" title="发表于 2024-05-05 09:43:26">2024-05-05</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2024/04/30/android/charles%E5%AE%89%E5%8D%93%E6%89%8B%E6%9C%BA%E6%8A%93%E5%8C%85/" title="charles 抓包"><img src="/blog/img/library1.jpeg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="charles 抓包"/></a><div class="content"><a class="title" href="/blog/2024/04/30/android/charles%E5%AE%89%E5%8D%93%E6%89%8B%E6%9C%BA%E6%8A%93%E5%8C%85/" title="charles 抓包">charles 抓包</a><time datetime="2024-04-30T06:49:29.279Z" title="发表于 2024-04-30 14:49:29">2024-04-30</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2024/04/26/python/13%E3%80%81playwright/" title="playwright"><img src="/blog/img/library1.jpeg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="playwright"/></a><div class="content"><a class="title" href="/blog/2024/04/26/python/13%E3%80%81playwright/" title="playwright">playwright</a><time datetime="2024-04-26T07:30:36.069Z" title="发表于 2024-04-26 15:30:36">2024-04-26</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2024 By 侯玉东</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/blog/js/utils.js"></script><script src="/blog/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.min.js"></script><div class="js-pjax"></div><div class="aplayer no-destroy" data-id="8873950678" data-server="netease" data-type="playlist" data-fixed="true" data-autoplay="true"> </div><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="false" data-click="false"></script><script defer="defer" id="fluttering_ribbon" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-fluttering-ribbon.min.js"></script><script id="click-heart" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/click-heart.min.js" async="async" mobile="false"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/metingjs/dist/Meting.min.js"></script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors = ["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"]

var pjax = new Pjax({
  elements: 'a:not([target="_blank"])',
  selectors: pjaxSelectors,
  cacheBust: false,
  analytics: false,
  scrollRestoration: false
})

document.addEventListener('pjax:send', function () {

  // removeEventListener
  btf.removeGlobalFnEvent('pjax')
  btf.removeGlobalFnEvent('themeChange')

  document.getElementById('rightside').classList.remove('rightside-show')
  
  if (window.aplayers) {
    for (let i = 0; i < window.aplayers.length; i++) {
      if (!window.aplayers[i].options.fixed) {
        window.aplayers[i].destroy()
      }
    }
  }

  typeof typed === 'object' && typed.destroy()

  //reset readmode
  const $bodyClassList = document.body.classList
  $bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')

  typeof disqusjs === 'object' && disqusjs.destroy()
})

document.addEventListener('pjax:complete', function () {
  window.refreshFn()

  document.querySelectorAll('script[data-pjax]').forEach(item => {
    const newScript = document.createElement('script')
    const content = item.text || item.textContent || item.innerHTML || ""
    Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
    newScript.appendChild(document.createTextNode(content))
    item.parentNode.replaceChild(newScript, item)
  })

  GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()

  typeof panguInit === 'function' && panguInit()

  // google analytics
  typeof gtag === 'function' && gtag('config', '', {'page_path': window.location.pathname});

  // baidu analytics
  typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);

  typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

  // prismjs
  typeof Prism === 'object' && Prism.highlightAll()
})

document.addEventListener('pjax:error', e => {
  if (e.request.status === 404) {
    pjax.loadUrl('/blog/404.html')
  }
})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>